<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Rust代码分析 - Rust知识解释智能体</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@11.8.0/styles/github.min.css">
    <style>
        body {
            margin: 0;
            padding: 0;
            min-height: 100vh;
            background: #f5f6fa;
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
        }
        .layout {
            display: flex;
            min-height: 100vh;
        }
        .sidebar {
            width: 420px;
            background: #fff;
            border-radius: 0 18px 18px 0;
            box-shadow: 2px 0 16px rgba(52,152,219,0.08);
            padding: 32px 24px 24px 24px;
            display: flex;
            flex-direction: column;
            align-items: flex-start;
            z-index: 2;
        }
        .sidebar h3 {
            margin-top: 0;
            color: #222;
            font-size: 1.2rem;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .sidebar .task-list {
            margin-top: 24px;
            width: 100%;
            overflow-y: auto;
            flex: 1;
        }
        .sidebar .task-list::-webkit-scrollbar {
            width: 6px;
            background: #f0f0f0;
        }
        .sidebar .task-list::-webkit-scrollbar-thumb {
            background: #e0e6ed;
            border-radius: 3px;
        }
        .main-content {
            flex: 1;
            display: flex;
            justify-content: center;
            align-items: flex-start;
            padding: 48px 0;
        }
        .editor-card {
            background: #fff;
            border-radius: 18px;
            box-shadow: 0 4px 24px rgba(52,152,219,0.10);
            padding: 48px 60px 36px 36px; /* 缩小padding */
            max-width: 1100px; /* 缩小最大宽度 */
            width: 100%;
            display: flex;
            flex-direction: column;
            align-items: center;
            margin-left:300px; /* 缩小左边距 */
        }
        .editor-title {
            font-size: 1.3rem;
            color: #222;
            font-weight: bold;
            margin-bottom: 0;
            display: flex;
            align-items: center;
            gap: 8px;
        }
        .blue-underline {
            width: 200px;
            height: 4px;
            background: #4f8cff;
            border-radius: 2px;
            margin: 10px 0 24px 0;
        }
        #monaco-editor {
            width: 100%;
            min-height: 400px;
            max-height:50vh;
            border-radius: 10px;
            border: 1.5px solid #e0e6ed;
            box-shadow: 0 2px 8px rgba(52,152,219,0.08);
            margin-bottom: 24px;
            background: #181c24;
            max-width: 1300px; /* 提高最大宽度 */
        }
        .button-group {
            display: flex;
            justify-content: center;
            align-items: center;
            gap: 18px;
            margin-bottom: 18px;
            width: 100%;
            max-width: 1300px; /* 提高最大宽度 */
        }
        .submit-btn, .run-btn {
            background: linear-gradient(90deg, #4f8cff 0%, #27ae60 100%);
            color: #fff;
            border: none;
            border-radius: 14px;
            padding: 12px 36px;
            font-size: 1.08rem;
            font-weight: 700;
            cursor: pointer;
            box-shadow: 0 2px 8px rgba(52,152,219,0.10);
            transition: all 0.18s cubic-bezier(.4,1.3,.6,1);
            margin: 0;
            display: flex;
            align-items: center;
            gap: 8px;
            letter-spacing: 0.5px;
        }
        .submit-btn:hover, .run-btn:hover {
            background: linear-gradient(90deg, #27ae60 0%, #4f8cff 100%);
        }
        .run-result, .analysis-result {
            background: #f8f9fa;
            border-radius: 8px;
            padding: 12px 10px;
            min-height: 40px;
            font-size: 0.98rem;
            color: #222;
            box-shadow: 0 2px 8px rgba(0,0,0,0.04);
            white-space: pre-wrap;
            word-break: break-all;
            width: 100%;
            margin-bottom: 0;
        }
        @media (max-width: 1000px) {
            .sidebar { display: none; }
            .main-content { padding: 12px 0; }
            .editor-card { max-width: 98vw; padding: 16px 4vw; }
        }
        @media (max-width: 600px) {
            .editor-title { font-size: 1.05rem; }
            .blue-underline { width: 120px; }
            .editor-card { padding: 8px 2vw; }
        }
    </style>
    <script src="https://unpkg.com/monaco-editor@0.34.1/min/vs/loader.js"></script>
    <script src="https://unpkg.com/mermaid@10.9.0/dist/mermaid.min.js"></script>
</head>
<body>
    <div class="layout">
        <div class="sidebar" id="examplesSidebar">
            <button onclick="window.location.href='/dashboard'" style="margin-bottom: 18px; background: #4f8cff; color: #fff; border: none; border-radius: 8px; padding: 8px 22px; font-size: 1rem; font-weight: 600; cursor: pointer; box-shadow: 0 2px 8px rgba(52,152,219,0.10); transition: all 0.18s;">
                ← 返回问答界面
            </button>
            <h3><i class="fas fa-tasks"></i> 编程任务</h3>
            <div class="task-list" id="examplesContent">
                <p>从问答界面获取的例题和案例将显示在这里。</p>
            </div>
        </div>
        <div class="main-content">
            <div class="editor-card">
                <div class="editor-title">
                    <i class="fas fa-code"></i> Rust 代码分析与在线运行
                </div>
                <div class="blue-underline"></div>
        <div id="monaco-editor"></div>
        <div class="button-group">
            <button type="button" class="run-btn" id="runRustBtn"><i class="fas fa-play"></i> 运行</button>
            <button type="button" class="submit-btn" id="analyzeBtn"><i class="fas fa-paper-plane"></i> 提交分析</button>
        </div>
        <div id="runResult" class="run-result" style="display:none;"></div>
        <div id="analysisResult" class="analysis-result">分析结果将在此处展示</div>
            </div>
        </div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/js/all.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
    <script>
    let monacoEditor;
    require.config({ paths: { 'vs': 'https://unpkg.com/monaco-editor@0.34.1/min/vs' }});
    require(['vs/editor/editor.main'], function() {
        monacoEditor = monaco.editor.create(document.getElementById('monaco-editor'), {
            value: '// 在此输入您的Rust代码\nfn main() {\n    println!("Hello, Rust!");\n}',
            language: 'rust',
            theme: 'vs-dark',
            fontSize: 16,
            minimap: { enabled: false },
            automaticLayout: true
        });
        fetchAndDisplayExamples();
    });
    async function fetchAndDisplayExamples() {
        // 优先从localStorage读取rust_examples
        let examples = localStorage.getItem('rust_examples');
        const container = document.getElementById('examplesContent');
        function beautifyContent(raw) {
            if (!raw) return '<div style="color:#888;">暂无编程任务。</div>';
            let html = '';
            // 练习部分
            const exerciseMatches = Array.from(raw.matchAll(/练习[0-9]+[\s\S]*?(?=(练习[0-9]+|综合案例|$))/g));
            exerciseMatches.forEach((match, idx) => {
                let block = match[0].trim();
                let lines = block.split('\n').filter(l => l.trim());
                let title = lines[0] || `练习${idx+1}`;
                let body = lines.slice(1).join('\n');
                html += `<div class="task-card" style="background:#f8f9fa;border-radius:12px;padding:18px 18px 14px 18px;margin-bottom:18px;border:1.5px solid #e0e6ed;box-shadow:0 2px 8px #4f8cff11;">
                    <div class="task-title" style="font-weight:bold;color:#1976d2;font-size:1.13rem;margin-bottom:10px;letter-spacing:1px;">${title}</div>
                    <pre style="color:#234;font-size:1.08rem;line-height:1.85;background:#f4f6fb;border-radius:8px;border:none;margin:0;padding:12px 14px 10px 14px;white-space:pre-wrap;">${body}</pre>
                </div>`;
            });
            // 综合案例部分
            const caseMatch = raw.match(/综合案例[\s\S]*/);
            if (caseMatch) {
                let block = caseMatch[0].trim();
                let lines = block.split('\n').filter(l => l.trim());
                let title = lines[0] || '综合案例';
                let body = lines.slice(1).join('\n');
                html += `<div class="task-card" style="background:#fffbe6;border-radius:12px;padding:18px 18px 14px 18px;margin-bottom:18px;border:1.5px solid #ffe58f;box-shadow:0 2px 8px #faad1411;">
                    <div class="task-title" style="font-weight:bold;color:#faad14;font-size:1.13rem;margin-bottom:10px;letter-spacing:1px;">${title}</div>
                    <pre style="color:#8c6d1f;font-size:1.08rem;line-height:1.85;background:#fffdf3;border-radius:8px;border:none;margin:0;padding:12px 14px 10px 14px;white-space:pre-wrap;">${body}</pre>
                </div>`;
            }
            return html || '<div style="color:#888;">暂无编程任务。</div>';
        }
        if (examples) {
            try {
                examples = JSON.parse(examples);
                let content = examples.code_practice || '';
                // 只展示“代码练习”及其后内容
                let codePracticeIndex = content.indexOf('代码练习');
                if (codePracticeIndex !== -1) {
                    content = content.substring(codePracticeIndex);
                }
                container.innerHTML = beautifyContent(content);
            } catch(e) {
                container.innerHTML = '<p style="color:#e74c3c;">编程任务加载失败</p>';
            }
        } else {
            try {
                const response = await fetch('/api/get_examples');
                const data = await response.json();
                if (data.status === 'success' && (data.data.examples.length > 0 || data.data.comprehensive_case)) {
                    let content = '';
                    if (data.data.examples.length > 0) {
                        content += data.data.examples.join('\n');
                    }
                    if (data.data.comprehensive_case) {
                        content += '\n' + data.data.comprehensive_case;
                    }
                    container.innerHTML = beautifyContent(content);
                } else {
                    container.innerHTML = '<div style="text-align: center; color: #999; padding: 20px;"><i class="fas fa-info-circle"></i><br>当前没有相关的编程任务</div>';
                }
            } catch (error) {
                console.error('获取编程任务失败:', error);
                container.innerHTML = '<div style="text-align: center; color: #e74c3c; padding: 20px;"><i class="fas fa-exclamation-triangle"></i><br>加载编程任务失败，请稍后重试</div>';
            }
        }
    }
    // 运行按钮事件
    document.addEventListener('DOMContentLoaded', function() {
        const runBtn = document.getElementById('runRustBtn');
        const runResultDiv = document.getElementById('runResult');
        if (runBtn) {
            runBtn.addEventListener('click', async function() {
                runResultDiv.style.display = 'block';
                runResultDiv.innerHTML = '<div style=\'font-weight:bold;color:#fff;background:#222;padding:6px 12px 4px 12px;border-radius:8px 8px 0 0;font-size:1rem;\'>运行结果</div>' +
                  '<pre id=\'runResultBox\' style=\'background:#181c24;color:#e8eaf6;padding:16px 14px 14px 14px;border-radius:0 0 8px 8px;margin:0;font-size:1.05rem;overflow-x:auto;\'>正在运行...</pre>';
                const code = monacoEditor.getValue();
                try {
                    const resp = await fetch('/api/run_rust_code', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({ code })
                    });
                    const data = await resp.json();
                    const resultBox = document.getElementById('runResultBox');
                    if (data.status === 'success') {
                        resultBox.textContent = (data.stdout && data.stdout.trim() ? data.stdout : '[无输出]') + (data.stderr ? ('\n[stderr]\n' + data.stderr) : '');
                    } else {
                        resultBox.textContent = (data.message || '运行失败') + (data.stderr ? ('\n' + data.stderr) : '');
                    }
                } catch (e) {
                    const resultBox = document.getElementById('runResultBox');
                    resultBox.textContent = '运行出错: ' + e;
                }
            });
        }
    });
    // 分析按钮事件
    document.getElementById('analyzeBtn').onclick = async function() {
        const analysisDiv = document.getElementById('analysisResult');
        analysisDiv.innerHTML = '<span style="color:#888;">正在分析，请稍候...</span>';
        const code = monacoEditor.getValue();
        let examples = localStorage.getItem('rust_examples');
        try {
            const resp = await fetch('/api/analyze_rust_code', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ code, examples })
            });
            const data = await resp.json();
            if (data.status === 'success') {
                let result = data.result || '';
                // 每一块用小卡片包裹，标题为“1. 题目归属判断”等
                function beautifyAnalysisSections(md) {
                    // 优化分块正则，支持多种常见大项标题格式
                    // 支持：### 1.、### 1、、### 一、、#### 1.、1. 、1、 、一、
                    const sectionRegex = /^(###|####)?\s*((\d+|[一二三四五六七八九十]+)[\.、])\s*[^\n]*$/gm;
                    let indices = [];
                    let match;
                    while ((match = sectionRegex.exec(md)) !== null) {
                        indices.push({ idx: match.index, title: match[0] });
                    }
                    let parts = [];
                    if (indices.length === 0) {
                        // 没有分块，整体渲染
                        let content = mdToOrderedList(md);
                        return `<div class='analysis-section-card' style='background:#fff;border-radius:8px;padding:18px 16px 14px 16px;margin-bottom:18px;border:1.5px solid #e0e6ed;box-shadow:0 2px 8px #4f8cff08;'>
                            <div class='analysis-section-title' style='font-weight:bold;color:#1976d2;font-size:1.08rem;margin-bottom:10px;'>代码分析结果</div>
                            <div class='analysis-section-content'>${content}</div>
                        </div>`;
                    }
                    for (let i = 0; i < indices.length; i++) {
                        let start = indices[i].idx;
                        let end = (i + 1 < indices.length) ? indices[i + 1].idx : md.length;
                        let sectionMd = md.slice(start, end).trim();
                        // 提取标题文本（保留数字和内容）
                        let titleLine = indices[i].title;
                        let titleText = titleLine.replace(/^(###|####)?\s*/, '');
                        // 去掉标题行再渲染内容，并去除内容中重复出现的标题（如1.题目归属判断等）
                        let sectionContentMd = sectionMd.replace(titleLine, '').trim();
                        // 去除内容开头的“1.题目归属判断”、“1、题目归属判断”、“一、题目归属判断”、“1. 正确性分析”、“**正确性分析**:”等
                        sectionContentMd = sectionContentMd.replace(/^(\s*[\d一二三四五六七八九十]+[\.、])?\s*(\*\*|__)?[\u4e00-\u9fa5A-Za-z0-9_（）()]+([:：\.]|\*\*|__)*\s*/u, '');
                        // 只对每个分块内容做分条转有序列表
                        let content = mdToOrderedList(sectionContentMd);
                        parts.push(`<div class='analysis-section-card' style='background:#fff;border-radius:8px;padding:18px 16px 14px 16px;margin-bottom:18px;border:1.5px solid #e0e6ed;box-shadow:0 2px 8px #4f8cff08;'>
                            <div class='analysis-section-title' style='font-weight:bold;color:#1976d2;font-size:1.08rem;margin-bottom:10px;'>${titleText}</div>
                            <div class='analysis-section-content'>${content}</div>
                        </div>`);
                    }
                    // 只返回分块卡片拼接
                    return parts.join('');
                }
                // 分点转有序列表函数，提升到外部作用域
                function mdToOrderedList(md) {
                    const lines = md.split(/\r?\n/);
                    let inList = false;
                    let html = '';
                    let listBuffer = [];
                    for (let line of lines) {
                        if (/^([*\-•]|\d+[\.、])\s+/.test(line)) {
                            inList = true;
                            listBuffer.push(line.replace(/^([*\-•]|\d+[\.、])\s+/, ''));
                        } else {
                            if (inList) {
                                html += '<ol style="margin:0 0 0 22px;padding:0 0 0 8px;">' + listBuffer.map(item => `<li>${item}</li>`).join('') + '</ol>';
                                listBuffer = [];
                                inList = false;
                            }
                            html += line ? `<div>${line}</div>` : '<br>';
                        }
                    }
                    if (inList && listBuffer.length > 0) {
                        html += '<ol style="margin:0 0 0 22px;padding:0 0 0 8px;">' + listBuffer.map(item => `<li>${item}</li>`).join('') + '</ol>';
                    }
                    return html;
                }
                analysisDiv.innerHTML = beautifyAnalysisSections(result);
            } else {
                analysisDiv.innerHTML = '<span style="color:#e74c3c;">' + (data.message || '分析失败') + '</span>';
            }
        } catch (e) {
            analysisDiv.innerHTML = '<span style="color:#e74c3c;">分析出错: ' + e + '</span>';
        }
    };
    </script>
</body>
</html> 